package tt.dz.service.imp.sys;

import java.math.BigDecimal;
import java.sql.Time;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import com.alibaba.fastjson.JSON;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.criterion.Example;
import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import tt.dz.dao.ext.charger.OmsChargerDao;
import tt.dz.dao.ext.charger.OmsChargerRateDao;
import tt.dz.dao.ext.charger.OmsChargerRateRepo;
import tt.dz.entity.base.JsonForList;
import tt.dz.entity.base.JsonPageForList;
import tt.dz.entity.base.OmsCommonParam;
import tt.dz.entity.charger.OmsCharger;
import tt.dz.entity.charger.OmsChargerRate;
import tt.dz.entity.charger.OmsChargerRateEntity;
import tt.dz.entity.charger.OmsChargerRateKey;
import tt.dz.entity.exception.BizException;
import tt.dz.entity.exception.OmsDaoException;
import tt.dz.mvc.model.SaveRateModel;
import tt.dz.service.imp.base.BaseService;
import tt.dz.service.sys.OmsChargerRateService;
import tt.dz.util.OmsConstant;
import tt.dz.util.OmsConstant.MsgCodeEnum;

@Service
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class OmsChargerRateServiceImpl extends BaseService implements OmsChargerRateService
{

	private Log log = LogFactory.getLog(OmsChargerRateServiceImpl.class);

	@Resource
	OmsChargerRateDao omsChargerRateDao;
	@Resource
	OmsChargerDao omsChargerDao;
	@Resource
	OmsChargerRateRepo omsChargerRateRepo;

	@Override
	public OmsChargerRate findOneExample(OmsChargerRate obj, String order, String sortVal)
	{
		return omsChargerRateDao.findOneExample(obj, order, sortVal);
	}

	@Override
	public JsonPageForList findRateGroup(OmsChargerRate obj, Integer pageNo, Integer pageSize, String sortName, Integer sortVal, String groupByStrs,Boolean queryTotal)
	{
		//		return omsChargerRateDao.findExampleBySql(obj, pageNo, pageSize, sortName, sortVal, "select rate_schema,serial_no,rate_name,charge_mode,fee_type,start_time,end_time,rate,oper_id,set_time,valid_flag from oms_charger_rate group by ", null);
		StringBuilder sb = new StringBuilder(" where 1 = 1 ");
		if (obj != null)
		{
			if (obj.getRate_schema() != null)
			{
				sb.append(" and rate_schema =" + obj.getRate_schema());
			}
			if (obj.getFee_type() != null)
			{
				sb.append(" and fee_type =" + obj.getFee_type());
			}
			if (obj.getDefault_for() != null && obj.getDefault_for() != "all" ) //前端没有端口号时传递all
			{
				sb.append(" and (default_ind = 0 or (default_ind = 1 and (default_for  ='" + obj.getDefault_for() +"' or default_for  = 'all')) )");
			}
		}

		List<OmsChargerRate> list_OmsChargerRate = omsChargerRateDao.findListByPageAndGroupAndOrderAndCondition(obj, sb.toString(), pageNo, pageSize, sortName, sortVal, groupByStrs);//"rate_schema"
		
		
		int total = 0;
		if (queryTotal) {
			try {
				total =  omsChargerRateDao.queryTotalBySql(new OmsChargerRate(), "select count(distinct(oms_charger_rate.rate_schema)) from oms_charger_rate " +sb.toString(), new ArrayList<Object>());
			} catch (Exception e) {
				total = 0;
				e.printStackTrace();
			}
		}
		
		JsonPageForList jfl = new JsonPageForList();
		jfl.setCode(MsgCodeEnum.SUCCESS.getMsgCode());
		jfl.setList(list_OmsChargerRate);
		jfl.setTotal(total);
		jfl.setMsg(MsgCodeEnum.SUCCESS.getMsgInfo());
		return jfl;
	}

	@Override
	public int save(OmsChargerRate obj)
	{
		try
		{
			int newRateSchema = omsChargerRateDao.findMaxRateSchema() + 1;
			obj.setRate_schema(newRateSchema);
		}
		catch (OmsDaoException e)
		{
			this.logError(e.getMessage(), e);
			return 0;
		}
		return omsChargerRateDao.save(obj);
	}

	@Override
	public int updateObject(OmsChargerRate obj)
	{
		return omsChargerRateDao.updateObject(obj);
	}

	@Override
	public int logicDelete(OmsChargerRate obj)
	{
		return omsChargerRateDao.LogicDeleteObject(obj);
	}

	//费用类型:1：预约费用；2：充电费用；3：充电服务费,0为尚未分配类型的费用d
	@Override
	public int bindChargers(String rate_schema, int fee_type, List<String> chargerIds)
	{
		//for循环，update桩表
		String rate_column = "rate_schema_charge_fee";
		switch (fee_type)
		{
			case 1:
				rate_column = "rate_schema_bespeak_fee";
				break;
			case 2:
				rate_column = "rate_schema_charge_fee";
				break;
			case 3:
				rate_column = "rate_schema_service_fee";
				break;
			default:
				return 0;
		}
		try
		{
			StringBuilder sb = new StringBuilder("update oms_charger  set  " + rate_column + " = " + rate_schema + " where charger_id in (");
			for (String chargerId : chargerIds)
			{
				sb.append("'" + chargerId + "',");
			}
			sb.deleteCharAt(sb.length() - 1);
			sb.append(")");
			omsChargerRateDao.exec(sb.toString());
			return 1;
		}
		catch (Exception e)
		{
			e.printStackTrace();
			return 0;
		}
	}

	@Override
	public JsonForList<?> findPageOrAll(OmsCommonParam buildQueryParam, OmsChargerRate rate)
	{
		try
		{
			List<OmsChargerRate> lst = omsChargerRateDao.pagingFind(buildQueryParam, rate);
			int total = 0;
			if (buildQueryParam.isQueryTotal())
			{
				total = omsChargerRateDao.queryTotalByObject(rate);
			}
			SimpleDateFormat format = new SimpleDateFormat("HH:mm");
			for (int i = 0; i < lst.size(); i++)
			{
				if (lst.get(0).getStart_time() != null)
				{
					lst.get(i).setStart_time_str(format.format(lst.get(0).getStart_time()));
				}
				if (lst.get(0).getEnd_time() != null)
				{
					lst.get(i).setEnd_time_str(format.format(lst.get(0).getEnd_time()));
				}
				if (lst.get(0).getSet_time() != null)
				{
					lst.get(i).setSet_time_str(format.format(lst.get(0).getSet_time()));
				}
			}
			return this.buildSuccessJsonForList(buildQueryParam, lst, total);
		}
		catch (Exception e)
		{
			this.logError(e.getMessage(), e);
			return this.buildError400JsonForList();
		}
	}

	@Override
	public int saveList(List<OmsChargerRate> objList)
	{
		try
		{
			int newRateSchema = omsChargerRateDao.findMaxRateSchema() + 1;
			for (OmsChargerRate chargerRate : objList)
			{
				chargerRate.setRate_schema(newRateSchema);
			}
			return omsChargerRateDao.saveList(objList);
		}
		catch (OmsDaoException e)
		{
			this.logError(e.getMessage(), e);
			return 0;
		}
	}

	@Override
	public JsonForList<?> findRate(String rateSchema)
	{
		OmsChargerRate rate = new OmsChargerRate();
		rate.setRate_schema(Integer.valueOf(rateSchema));
		List<OmsChargerRate> list = omsChargerRateDao.findListByCondition(rate, "");
		JsonForList<OmsChargerRate> json = new JsonForList<OmsChargerRate>(list, "200", "ok");
		return json;
	}

	@Override
	public int deleteByRateSchema(String rate_schema)
	{
		boolean result = omsChargerRateDao.exec("delete from oms_charger_rate where rate_schema =" + rate_schema);
		if (result)
		{
			return 1;
		}
		else
		{
			return 0;
		}
	}

	@Override
	public List<OmsCharger> findChargersBySchema(String rate_schema)
	{
		List<OmsCharger> list = omsChargerDao
				.findListByCondition(new OmsCharger(), " where rate_schema_bespeak_fee =" + rate_schema + " or rate_schema_charge_fee = " + rate_schema + " or rate_schema_service_fee = " + rate_schema);
		return list;
	}

	@Override
	public List<OmsCharger> findNullChargers(String fee_type,String default_for)
	{
		String condition = "";
		switch (fee_type)
		{
			case "1":
				condition = " where valid_flag = 1 and rate_schema_bespeak_fee = 0 or rate_schema_bespeak_fee is null";
				break;
			case "2":
				condition = " where valid_flag = 1 and rate_schema_charge_fee = 0 or rate_schema_charge_fee is null";
				break;
			case "3":
				condition = " where valid_flag = 1 and rate_schema_service_fee = 0 or rate_schema_service_fee is null";
				break;
			case "9":
				condition = " where valid_flag = 1 and (rate_schema_bespeak_fee = 0 or rate_schema_bespeak_fee is null) " + "and (rate_schema_charge_fee = 0 or rate_schema_charge_fee is null) "
						+ "and (rate_schema_service_fee = 0 or rate_schema_service_fee is null)";
				break;
			default:
				return null;
		}
		// 协议版本  1.x/2.x/all、null
		if ("1.x".equals(default_for)) {
			condition = condition+ " and protocol_version like '01%'";
		}else if ("2.x".equals(default_for)) {
			condition = condition+ " and protocol_version like '02%'";
		}
		List<OmsCharger> list = omsChargerDao.findListByCondition(new OmsCharger(), condition);
		return list;
	}

	@Override
	public List<OmsChargerRate> findByChargerId(String charger_id)
	{
		OmsCharger charger_query = new OmsCharger();
		charger_query.setCharger_id(charger_id);
		OmsCharger charger = omsChargerDao.findOneExample(charger_query, null, null);
		StringBuilder sb = new StringBuilder("where 1 = 1");
		if (charger == null)
		{
			return null;
		}
		if (charger.getRate_schema_bespeak_fee() != null && charger.getRate_schema_bespeak_fee() > 0)
		{
			sb.append("rate_schema = " + charger.getRate_schema_bespeak_fee());
		}
		if (charger.getRate_schema_charge_fee() != null && charger.getRate_schema_charge_fee() > 0)
		{
			sb.append(" or rate_schema = " + charger.getRate_schema_charge_fee());
		}
		if (charger.getRate_schema_service_fee() != null && charger.getRate_schema_service_fee() > 0)
		{
			sb.append(" or rate_schema = " + charger.getRate_schema_service_fee());
		}
		List<OmsChargerRate> list = omsChargerRateDao.findListByCondition(new OmsChargerRate(), sb.toString());
		return list;
	}

	@Override
	public int unBindChargers(Integer fee_type, List<String> chargerIdList)
	{
		//for循环，update桩表
		String rate_column = "rate_schema_charge_fee";
		switch (fee_type)
		{
			case 1:
				rate_column = "rate_schema_bespeak_fee";
				break;
			case 2:
				rate_column = "rate_schema_charge_fee";
				break;
			case 3:
				rate_column = "rate_schema_service_fee";
				break;
			default:
				return 0;
		}
		try
		{
			StringBuilder sb = new StringBuilder("update oms_charger  set  " + rate_column + " = " + null + " where charger_id in (");
			for (String chargerId : chargerIdList)
			{
				sb.append("'" + chargerId + "',");
			}
			sb.deleteCharAt(sb.length() - 1);
			sb.append(")");
			omsChargerRateDao.exec(sb.toString());
			return 1;
		}
		catch (Exception e)
		{
			e.printStackTrace();
			return 0;
		}
	}

	@Override
	public void saveChargeRate(SaveRateModel model) throws BizException
	{

		OmsChargerRateEntity vo = new OmsChargerRateEntity();
		if (model.getRate_schema() == null)
			vo.setRateSchema(omsChargerRateRepo.selectNewSchemaNo());    
		else
			vo.setRateSchema(model.getRate_schema());

		if (omsChargerRateRepo.getSumByRateNameAndRateSchema(model.getRate_name(), vo.getRateSchema()) > 0)
			throw new BizException("重复的费率方案名");
		if (model.getDefault_ind() == 1)
			if (omsChargerRateRepo.getSumByDefaultIndAndDefaultForAndRateSchemaAndFeeType(model.getDefault_for(), vo.getRateSchema(), model.getFee_type()) > 0)
				throw new BizException("该类型的默认方案已经存在");

		vo.setChargeMode(model.getCharge_mode());
		vo.setDefaultFor(model.getDefault_for());
		vo.setDefaultInd(model.getDefault_ind());
		vo.setFeeType(model.getFee_type());
		vo.setRateName(model.getRate_name());
		vo.setSetTime(new Date());
		vo.setValidFlag(1);
		if(model.getValid_flag() != null)
			vo.setValidFlag(model.getValid_flag());
		vo.setStartTime(null);
		vo.setEndTime(null);

		List<OmsChargerRateEntity> list_vo = new ArrayList<>();
		List<Integer> list_serialNo = new ArrayList<>();
		if (model.getCharge_mode() == OmsConstant.PaymentMode.ByFrequency)
		{
			List<String> rateList = JSON.parseArray(model.getRate(), String.class);
			if (rateList == null || rateList.isEmpty())
				throw new BizException("Rate is empty");
			vo.setSerialNo(1);
			vo.setRate(new BigDecimal(rateList.get(0)));
			list_vo.add(vo);
			list_serialNo.add(1);
		}
		else if (model.getCharge_mode() == OmsConstant.PaymentMode.ByTime)
		{
			List<String> startTimeList = JSON.parseArray(model.getStart_time(), String.class);
			List<String> endTimeList = JSON.parseArray(model.getEnd_time(), String.class);
			List<String> rateList = JSON.parseArray(model.getRate(), String.class);

			if (startTimeList == null || startTimeList.isEmpty() || endTimeList == null || endTimeList.isEmpty() || rateList == null || rateList.isEmpty())
				throw new BizException(" Element is empty ");

			if (startTimeList.size() != endTimeList.size() || startTimeList.size() != rateList.size())
				throw new BizException(" Element number does not tally ");

			SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
			try
			{
				for (int i = 0; i < startTimeList.size(); i++)
				{
					OmsChargerRateEntity entity = new OmsChargerRateEntity(vo);
					entity.setStartTime(new Time(sdf.parse(startTimeList.get(i)).getTime()));
					entity.setEndTime(new Time(sdf.parse(endTimeList.get(i)).getTime()));
					entity.setRate(new BigDecimal(rateList.get(i)));
					entity.setSerialNo(i + 1);

					list_vo.add(entity);
					list_serialNo.add(entity.getSerialNo());
					log.info(entity);
				}
			}
			catch (ParseException e)
			{
				log.error(e.getMessage(), e);
				throw new BizException(e);
			}
			log.info(list_vo.size());

		}
		omsChargerRateRepo.delete(omsChargerRateRepo.findByRateSchemaAndSerialNoNotIn(vo.getRateSchema(), list_serialNo));
		omsChargerRateRepo.save(list_vo);

	}
}
